/**
 * 行政机构选择器
 */
import React from 'react';
import { Spin, TreeSelect } from 'antd';
import { useRequest } from '@/hooks';
import { fetchCompany } from '../service';

const getTreeData = (
    data = [],
    fieldsName = { value: 'organizationCode', title: 'organizationName' },
    disabledKeys = []
) =>
    data?.map(item => ({
        ...item,
        value: item[fieldsName.value],
        title: item[fieldsName.title],
        key: item[fieldsName.value],
        disabled: disabledKeys.includes(item[fieldsName.value]),
        children: item.children ? getTreeData(item.children, fieldsName, disabledKeys) : item.children
    }));

const filterTree = (tree = [], obj = {}, fieldsName = { value: 'organizationCode', title: 'organizationName' }) =>
    tree.forEach(item => {
        const { children } = item;
        // eslint-disable-next-line no-param-reassign
        obj[item[fieldsName.value]] = {
            ...item,
            value: item[fieldsName.value],
            title: item[fieldsName.title]
        };
        if (children && children.length > 0) {
            filterTree(children, obj, fieldsName);
        }
    });

const filterTree2 = (tree = [], arr = []) =>
    tree.forEach(({ props }) => {
        const { children, organizationCode } = props;
        arr.push(organizationCode);
        if (children && children.length > 0) {
            filterTree2(children, arr);
        }
    });

const getChildrenCodes = arr => {
    if (!arr || arr.length === 0) {
        return [];
    }
    const orgCodes = [];
    filterTree2(arr, orgCodes);
    return orgCodes;
};

const Company = React.forwardRef(
    (
        { value, onChange, requestParams, style, disabledKeys, permissionsLimit = true, treeCheckStrictly, ...rest },
        ref
    ) => {
        const { data, loading } = useRequest(() =>
            fetchCompany({
                organizationPermissions: permissionsLimit ? 1 : 0,
                showTreeFlag: 1,
                ...requestParams
            })
        );

        const treeData = React.useMemo(() => {
            const finalData = Array.isArray(data?.data) ? data?.data : [];
            return getTreeData(finalData, undefined, disabledKeys);
        }, [data, disabledKeys]);

        const treeDataAll = React.useMemo(() => {
            const arr = {};
            const finalData = Array.isArray(data?.data) ? data?.data : [];
            filterTree(finalData, arr);
            return arr;
        }, [data]);

        const getFinalValue = () => {
            if (value && value.length > 0) {
                if (treeCheckStrictly) {
                    return value.map(item => {
                        if (typeof item === 'string') {
                            return {
                                label: treeDataAll[item]?.title,
                                value: item
                            };
                        }
                        return item;
                    });
                }
                return value;
            }
            return undefined;
        };

        const handleChange = (_value, _label, _extra) => {
            if (onChange) {
                if (treeCheckStrictly && _value && _value.length > 0) {
                    const { checked, triggerNode } = _extra;
                    const {
                        props: { organizationCode, children = [] }
                    } = triggerNode;
                    const codes = getChildrenCodes(children);
                    const companyCodeList = _value?.map(item => item?.value);
                    if (checked) {
                        onChange(
                            [...new Set(companyCodeList.concat([organizationCode]).concat(codes))] || undefined,
                            _label,
                            _extra
                        );
                    } else {
                        onChange(
                            companyCodeList.filter(item => item !== organizationCode && !codes.includes(item)),
                            _label,
                            _extra
                        );
                    }
                    return;
                }
                onChange(_value, _label, _extra);
            }
        };

        return (
            <Spin spinning={loading}>
                <TreeSelect
                    ref={ref}
                    value={getFinalValue()}
                    onChange={handleChange}
                    treeData={treeData}
                    allowClear
                    placeholder="请选择行政机构"
                    showSearch
                    treeNodeFilterProp="title"
                    treeDefaultExpandAll
                    style={{ width: 170, ...style }}
                    dropdownStyle={{ maxHeight: 250, overflowY: 'visible' }}
                    getPopupContainer={trigger => trigger.parentNode}
                    showCheckedStrategy={treeCheckStrictly ? TreeSelect.SHOW_ALL : TreeSelect.SHOW_CHILD}
                    treeCheckStrictly={treeCheckStrictly}
                    {...rest}
                />
            </Spin>
        );
    }
);

export default Company;
